package qualomelhor.gwt.modules.client;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import qualomelhor.database.Categoria;
import qualomelhor.database.NotaPropriedade;
import qualomelhor.database.Produto;
import qualomelhor.database.PropriedadeProduto;
import qualomelhor.database.Usuario;

import com.google.appengine.api.datastore.Blob;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.dom.client.DoubleClickHandler;

public class MergeProdutos implements EntryPoint {
	private Label lbId;
	private TextBox txtNomeProdutoFinal;
	private TextBox txtDescricaoFinal;
	private ListBox cbCategoriaFinal;
	private TextBox txtCategoriaFinal;
	private TextBox txtEnderecoFotoMiniFinal;
	private TextBox[] txtEnderecoFotoFinal;
	//private CheckBox ckBloqueado;
	private ArrayList<Categoria> listCategorias;
	private ISessionSuportServiceAsync serviceSupportSvc = GWT.create(ISessionSuportService.class);
	private TextBox[] txtNomeBuscaFinal;
	private Produto prod1;
	private Produto prod2;
	private Produto prodFinal;

	public static native void showDivBloqueio()  /*-{
		//$wnd.alert("teste = " + $doc.getElementById("divBloqueio").style.display);
		$doc.getElementById("divBloqueio").style.display="block";
		$doc.getElementById("divBloqueioSolido").style.display="block";
	}-*/;

	public static native void hideDivBloqueio()  /*-{
		//$wnd.alert("teste = " + $doc.getElementById("divBloqueio").style.display);
		$doc.getElementById("divBloqueio").style.display="none";
		$doc.getElementById("divBloqueioSolido").style.display="none";
	}-*/;

	@Override
	public void onModuleLoad() {
		carregaSessaoAtual();
	}

	private void carregaFormMergeProduto() {
		RootPanel rootPanel = RootPanel.get("divCadastro");
		rootPanel.clear();

		FlexTable tbMergeProduto = new FlexTable();
		rootPanel.add(tbMergeProduto);
		tbMergeProduto.setBorderWidth(1);

		tbMergeProduto.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				FlexTable tb = (FlexTable)event.getSource();
				Cell c = tb.getCellForEvent(event);
				//Window.alert("(lin, col) = (" + c.getRowIndex() + ", " + c.getCellIndex() + ")");
				switch (c.getRowIndex()) {
				case 1:
					if (c.getCellIndex() == 1) {
						txtNomeProdutoFinal.setText(prod1.getNomeProduto());
					} else if (c.getCellIndex() == 2) {
						txtNomeProdutoFinal.setText(prod2.getNomeProduto());
					}
					break;

				case 2:
					if (c.getCellIndex() == 1) {
						txtDescricaoFinal.setText(prod1.getDescricao());
					} else if (c.getCellIndex() == 2) {
						txtDescricaoFinal.setText(prod2.getDescricao());
					}
					break;
					
				case 3:
					if (c.getCellIndex() == 1) {
						if (prod1.getEnderecoFotoMini() != null && !prod1.getEnderecoFotoMini().equals("")) {
							txtEnderecoFotoMiniFinal.setText(prod1.getEnderecoFotoMini());
							tb.setHTML(3, 3, "<img style='width:50px; height: 50px;' src='" + prod1.getEnderecoFotoMini() + "'><BR>[" + prod1.getEnderecoFotoMini() + "]");
						}
					
					} else if (c.getCellIndex() == 2) {
						if (prod2.getEnderecoFotoMini() != null && !prod2.getEnderecoFotoMini().equals("")) {
							txtEnderecoFotoMiniFinal.setText(prod2.getEnderecoFotoMini());
							tb.setHTML(3, 3, "<img style='width:50px; height: 50px;' src='" + prod2.getEnderecoFotoMini() + "'><BR>[" + prod2.getEnderecoFotoMini() + "]");
						}
					}
					break;

				case 4:
					if (c.getCellIndex() == 1) {
						txtCategoriaFinal.setText(prod1.getIdCategoria().toString());
					} else if (c.getCellIndex() == 2) {
						txtCategoriaFinal.setText(prod2.getIdCategoria().toString());
					}
					break;
				}
			}
		});

		tbMergeProduto.setHTML(0, 0, "Item");
		tbMergeProduto.setHTML(0, 1, "Produto1");
		tbMergeProduto.setHTML(0, 2, "Produto2");
		tbMergeProduto.setHTML(0, 3, "ProdutoFinal");

		tbMergeProduto.setHTML(1, 0, "Nome:");
		tbMergeProduto.setHTML(1, 1, prod1.getNomeProduto());
		tbMergeProduto.setHTML(1, 2, prod2.getNomeProduto());
		txtNomeProdutoFinal = new TextBox();
		tbMergeProduto.setWidget(1, 3, txtNomeProdutoFinal);

		tbMergeProduto.setHTML(2, 0, "Descrição:");
		tbMergeProduto.setHTML(2, 1, prod1.getDescricao());
		tbMergeProduto.setHTML(2, 2, prod2.getDescricao());
		txtDescricaoFinal = new TextBox();
		tbMergeProduto.setWidget(2, 3, txtDescricaoFinal);

		tbMergeProduto.setHTML(3, 0, "Foto mini:");
		if (!prod1.getEnderecoFotoMini().equals("")) {
			tbMergeProduto.setHTML(3, 1, "<img style='width:50px; height: 50px;' src='" + prod1.getEnderecoFotoMini() + "'><BR>[" + prod1.getEnderecoFotoMini() + "]");
		} else {
			tbMergeProduto.setHTML(3, 1, "BRANCO");
		}
		if (!prod2.getEnderecoFotoMini().equals("")) {
			tbMergeProduto.setHTML(3, 2, "<img style='width:50px; height: 50px;' src='" + prod2.getEnderecoFotoMini() + "'><BR>[" + prod2.getEnderecoFotoMini() + "]");
		} else {
			tbMergeProduto.setHTML(3, 2, "BRANCO");
		}
		tbMergeProduto.setHTML(3, 3, "");


		tbMergeProduto.setHTML(4, 0, "Categoria Pai:");
		tbMergeProduto.setHTML(4, 1, prod1.getIdCategoria().toString());
		tbMergeProduto.setHTML(4, 2, prod2.getIdCategoria().toString());
		txtCategoriaFinal = new TextBox();
		tbMergeProduto.setWidget(4, 3, txtCategoriaFinal);


		tbMergeProduto.setHTML(5, 0, "Lista Busca:");
		final int numBuscasMax = prod1.getListBusca().size() + prod2.getListBusca().size();
		FlexTable tbListaBuscasFinal = new FlexTable();
		txtNomeBuscaFinal = new TextBox[numBuscasMax];
		for (int i = 0; i < numBuscasMax; i++) {
			txtNomeBuscaFinal[i] = new TextBox();
			tbListaBuscasFinal.setWidget(i, 0, txtNomeBuscaFinal[i]);
		}

		FlexTable tbListaBuscaProd1 = new FlexTable();
		tbListaBuscaProd1.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				FlexTable tb = (FlexTable)event.getSource();
				Cell c = tb.getCellForEvent(event);
				Window.alert("Celula clicada:" + c.getRowIndex());
				Window.alert("Busca:" + prod1.getListBusca().get(c.getRowIndex()));
				boolean encontrado = false;
				int i = 0;
				for (; i < numBuscasMax; i++) {
					if (txtNomeBuscaFinal[i].getText().equals(prod1.getListBusca().get(c.getRowIndex()))) {
						encontrado = true;
						break;
					}
					if (txtNomeBuscaFinal[i].getText().equals("")) {
						break;
					}
				}
				Window.alert("encontrado:" + encontrado + "i:" + i);
				if (!encontrado) {
					txtNomeBuscaFinal[i].setText(prod1.getListBusca().get(c.getRowIndex()));	
				}
			}
		});
		for (int i = 0; i < prod1.getListBusca().size(); i++) {
			tbListaBuscaProd1.setHTML(i, 0, prod1.getListBusca().get(i));
		}
		tbMergeProduto.setWidget(5, 1, tbListaBuscaProd1);
		
		
		FlexTable tbListaBuscaProd2 = new FlexTable();
		tbListaBuscaProd2.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				FlexTable tb = (FlexTable)event.getSource();
				Cell c = tb.getCellForEvent(event);
				Window.alert("Celula clicada:" + c.getRowIndex());
				Window.alert("Busca:" + prod2.getListBusca().get(c.getRowIndex()));
				boolean encontrado = false;
				int i = 0;
				for (; i < numBuscasMax; i++) {
					if (txtNomeBuscaFinal[i].getText().equals(prod2.getListBusca().get(c.getRowIndex()))) {
						encontrado = true;
						break;
					}
					if (txtNomeBuscaFinal[i].getText().equals("")) {
						break;
					}
				}
				Window.alert("encontrado:" + encontrado + "i:" + i);
				if (!encontrado) {
					txtNomeBuscaFinal[i].setText(prod2.getListBusca().get(c.getRowIndex()));	
				}
			}
		});
		for (int i = 0; i < prod2.getListBusca().size(); i++) {
			tbListaBuscaProd2.setHTML(i, 0, prod2.getListBusca().get(i));
		}
		tbMergeProduto.setWidget(5, 2, tbListaBuscaProd2);
		tbMergeProduto.setWidget(5, 3, tbListaBuscasFinal);

		txtEnderecoFotoMiniFinal = new TextBox();

		tbMergeProduto.setHTML(6, 0, "Fotos:");
		int numFotos = (prod1.getListEnderecoFoto().size() > prod2.getListEnderecoFoto().size())?prod1.getListEnderecoFoto().size():prod2.getListEnderecoFoto().size();
		final int numFotosMax = prod1.getListEnderecoFoto().size() + prod2.getListEnderecoFoto().size();
		FlexTable tbListaFotosFinal = new FlexTable();
		txtEnderecoFotoFinal = new TextBox[numFotosMax];
		for (int i = 0; i < numFotosMax; i++) {
			txtEnderecoFotoFinal[i] = new TextBox();
			tbListaFotosFinal.setWidget(i, 0, txtEnderecoFotoFinal[i]);
		}

		FlexTable tbListaFotosProd1 = new FlexTable();
		tbListaFotosProd1.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				FlexTable tb = (FlexTable)event.getSource();
				Cell c = tb.getCellForEvent(event);
				Window.alert("Celula clicada:" + c.getRowIndex());
				Window.alert("Foto:" + prod1.getListEnderecoFoto().get(c.getRowIndex()));
				boolean encontrado = false;
				int i = 0;
				for (; i < numFotosMax; i++) {
					if (txtEnderecoFotoFinal[i].getText().equals(prod1.getListEnderecoFoto().get(c.getRowIndex()))) {
						encontrado = true;
						break;
					}
					if (txtEnderecoFotoFinal[i].getText().equals("")) {
						break;
					}
				}
				Window.alert("encontrado:" + encontrado + "i:" + i);
				if (!encontrado) {
					txtEnderecoFotoFinal[i].setText(prod1.getListEnderecoFoto().get(c.getRowIndex()));	
				}
			}
		});

		FlexTable tbListaFotosProd2 = new FlexTable();
		tbListaFotosProd2.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				FlexTable tb = (FlexTable)event.getSource();
				Cell c = tb.getCellForEvent(event);
				Window.alert("Celula clicada:" + c.getRowIndex());
				Window.alert("Foto:" + prod2.getListEnderecoFoto().get(c.getRowIndex()));
				boolean encontrado = false;
				int i = 0;
				for (; i < numFotosMax; i++) {
					if (txtEnderecoFotoFinal[i].getText().equals(prod2.getListEnderecoFoto().get(c.getRowIndex()))) {
						encontrado = true;
						break;
					}
					if (txtEnderecoFotoFinal[i].getText().equals("")) {
						break;
					}
				}
				Window.alert("encontrado:" + encontrado + "i:" + i);
				if (!encontrado) {
					txtEnderecoFotoFinal[i].setText(prod2.getListEnderecoFoto().get(c.getRowIndex()));	
				}
			}
		});

		for (int i = 0; i < numFotos; i++) {
			if (i < prod1.getListEnderecoFoto().size()) {
				tbListaFotosProd1.setHTML(i, 0, "<img style='width:100px; height:100px;' src='" + prod1.getListEnderecoFoto().get(i) + "'>");
			}

			if (i < prod2.getListEnderecoFoto().size()) {
				tbListaFotosProd2.setHTML(i, 0, "<img style='width:100px; height:100px;' src='" + prod1.getListEnderecoFoto().get(i) + "'>");
			}
		}

		tbMergeProduto.setWidget(6, 1, tbListaFotosProd1);
		tbMergeProduto.setWidget(6, 2, tbListaFotosProd2);
		tbMergeProduto.setWidget(6, 3, tbListaFotosFinal);

		Button btnSalvar = new Button("Salvar Produto");
		btnSalvar.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				Window.alert("vai salvar o produto...");
				prodFinal = new Produto(txtNomeProdutoFinal.getText(), txtDescricaoFinal.getText(), Long.parseLong(txtCategoriaFinal.getText()), new ArrayList<String>(0), new ArrayList<Blob>(0), txtEnderecoFotoMiniFinal.getText(), new Date());
				for (int i = 0; i < txtNomeBuscaFinal.length; i++) {
					prodFinal.getListBusca().add(txtNomeBuscaFinal[i].getText());
				}
				for (int i = 0; i < txtEnderecoFotoFinal.length; i++) {
					prodFinal.getListEnderecoFoto().add(txtEnderecoFotoFinal[i].getText());
				}

				if (prod1.getMapNotaPropriedade() != null) {
					Iterator<Entry<PropriedadeProduto, NotaPropriedade>> itMap = prod1.getMapNotaPropriedade().entrySet().iterator();
					while (itMap.hasNext()) {
						Entry<PropriedadeProduto, NotaPropriedade> entry = itMap.next();
						prodFinal.getMapNotaPropriedade().put(entry.getKey(), entry.getValue());
					}
				}

				if (prod2.getMapNotaPropriedade() != null) {
					Iterator<Entry<PropriedadeProduto, NotaPropriedade>> itMap2 = prod2.getMapNotaPropriedade().entrySet().iterator();
					while (itMap2.hasNext()) {
						Entry<PropriedadeProduto, NotaPropriedade> entry = itMap2.next();
						if (prodFinal.getMapNotaPropriedade().containsKey(entry.getKey())) {
							prodFinal.getMapNotaPropriedade().put(entry.getKey(), entry.getValue());
						}
					}
				}

				Window.alert("prodFinal montado.. vai salvar..");
				salvaProdutoMerge(prodFinal, prod1.getId(), prod2.getId());
			}
		});
		rootPanel.add(btnSalvar);

		//****************************
		//Analise automatica
		if (prod1.getNomeProduto().equals(prod2.getNomeProduto())) {
			txtNomeProdutoFinal.setText(prod1.getNomeProduto());
		}

		if (prod1.getDescricao().equals(prod2.getDescricao())) {
			txtDescricaoFinal.setText(prod1.getDescricao());
		}

		if (prod1.getEnderecoFotoMini().equals(prod2.getEnderecoFotoMini())) {
			txtEnderecoFotoMiniFinal.setText(prod1.getEnderecoFotoMini());
		}

		int cont = 0;
		for (int i = 0; i < prod1.getListBusca().size(); i++) {
			if (prod2.getListBusca().contains(prod1.getListBusca().get(i))) {
				txtNomeBuscaFinal[cont].setText(prod1.getListBusca().get(i));
			}
		}

		cont = 0;
		for (int i = 0; i < prod1.getListEnderecoFoto().size(); i++) {
			if (prod2.getListEnderecoFoto().contains(prod1.getListEnderecoFoto().get(i))) {
				txtEnderecoFotoFinal[cont].setText(prod1.getListEnderecoFoto().get(i));
			}
		}
		//****************************
	}

	private void salvaProdutoMerge(Produto pNovo, Long pAnt1, Long pAnt2) {
		if (serviceSupportSvc == null) {
			serviceSupportSvc = GWT.create(ISessionSuportService.class);
		}

		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
			
			@Override
			public void onUncaughtException(Throwable e) {
				e.printStackTrace();
				System.out.println("Excecao nao tratada em Horario Carrega Sessao !!!!!!!!!!");
			}
		});

		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");
			}

			@Override
			public void onSuccess(Boolean b) {
				if (!b) {
					Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");	
				} else {
					Window.alert("Produto Merge Salvo com sucesso!");
					Window.Location.replace("/normalizaProduto.jsp");
				}
				
			}
		};

		Window.alert("Vai salvar o merge!");
		serviceSupportSvc.gravaProdutoMerge(pNovo, pAnt1, pAnt2, callback);
	}

	void carregaCategorias (boolean recarregar) {
		if (serviceSupportSvc == null) {
			serviceSupportSvc = GWT.create(ISessionSuportService.class);
		}

		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
			@Override
			public void onUncaughtException(Throwable e) {
				e.printStackTrace();
				System.out.println("Excecao nao tratada em Horario Carrega Sessao !!!!!!!!!!");
			}
		});

		AsyncCallback<ArrayList<Categoria>> callback = new AsyncCallback<ArrayList<Categoria>>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");
			}

			@Override
			public void onSuccess(ArrayList<Categoria> result) {
				listCategorias = result;
				carregaFormMergeProduto();
			}
		};

		serviceSupportSvc.getListCategorias(recarregar, callback);
	}

	private void carregaSessaoAtual() {
		if (serviceSupportSvc == null) {
			serviceSupportSvc = GWT.create(ISessionSuportService.class);
		}

		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
			@Override
			public void onUncaughtException(Throwable e) {
				e.printStackTrace();
				System.out.println("Excecao nao tratada em Horario Carrega Sessao !!!!!!!!!!");
			}
		});

		AsyncCallback<HashMap<String, Object>> callback = new AsyncCallback<HashMap<String, Object>>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");
			}

			@Override
			public void onSuccess(HashMap<String, Object> mapSession) {
				if (mapSession != null) {
					prod1 = (Produto)mapSession.get("PRODUTOMERGE1");
					prod2 = (Produto)mapSession.get("PRODUTOMERGE2");
				} else {
					Window.alert("erro sessao nao foi carregada! Reinicie esta pagina!");
				}

				carregaFormMergeProduto();
			}
		};
		Window.alert("carregando sessao...");
		serviceSupportSvc.carregaSessaoAtual(callback);
	}
}